package com.ling.greedy.snake.game.ui.pages.game

import android.annotation.SuppressLint
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import com.ling.greedy.snake.game.model.GameStatus
import com.ling.greedy.snake.game.ui.pages.game.mvi.GameViewModel
import com.ling.greedy.snake.game.ui.pages.game.widget.GameOverDialog
import com.ling.greedy.snake.game.ui.pages.game.widget.GameTitle
import com.ling.greedy.snake.game.ui.pages.game.widget.GameTouchPad
import com.ling.greedy.snake.game.ui.theme.BORDER_COLOR
import com.ling.greedy.snake.game.ui.theme.FONT_COLOR
import com.ling.greedy.snake.game.ui.theme.FOOD_COLOR
import com.ling.greedy.snake.game.ui.theme.GAME_BG
import com.ling.greedy.snake.game.ui.theme.PAD_BG

/**
 * @author Ling
 * @date :2025/7/3 15:41
 */

@SuppressLint("UseOfNonLambdaOffsetOverload")
@Composable
fun GamePage(){

    val vm = viewModel(GameViewModel::class)
    val state = vm.gameState.collectAsStateWithLifecycle()


    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(GAME_BG),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        GameTitle(
            score = state.value.score,
            modifier = Modifier
                .statusBarsPadding()
                .height(56.dp)
        )

        Box(
            modifier = Modifier.weight(1f).fillMaxWidth().padding(horizontal = 20.dp)
        ){
            BoxWithConstraints {
                val cellSize = remember(maxWidth, maxHeight) { maxWidth / vm.gameCol }
                val boardWidth = remember { cellSize * vm.gameCol }
                // 然后计算最多能容纳几行（向下取整）
                val gameRow = remember(maxHeight, cellSize) { (maxHeight / cellSize).toInt() }
                val boardHeight = remember { cellSize * gameRow }
                vm.initGamePadSize(gameRow)
                // 居中绘制
                Box(
                    modifier = Modifier
                        .size(boardWidth, boardHeight)
                        .align(Alignment.Center)
                        .clip(RoundedCornerShape(10.dp))
                        .background(PAD_BG)
                ){
                    //食物
                    Box(Modifier
                        .offset(
                            x =  (state.value.food.x * cellSize.value).dp ,
                            y =  (state.value.food.y * cellSize.value).dp
                        )
                        .background(FOOD_COLOR)
                        .size(cellSize)
                    )

                    // 绘制蛇
                    state.value.snake.forEach { point ->
                        val animatedX by animateDpAsState(
                            targetValue = (point.x * cellSize.value).dp,
                            animationSpec = tween(durationMillis = 100) // 调整动画时长
                        )
                        val animatedY by animateDpAsState(
                            targetValue = (point.y * cellSize.value).dp,
                            animationSpec = tween(durationMillis = 100)
                        )

                        Box(
                            modifier = Modifier
                                .offset(
                                    x = animatedX,
                                    y = animatedY
                                )
                                .size(cellSize)
                                .background(FONT_COLOR)
                        )
                    }
                }
            }
        }

        Box(
            Modifier.padding(horizontal = 20.dp , vertical = 10.dp)
        ){
            GameTouchPad(
                minScrollSize = 5.dp,
                modifier = Modifier
                    .fillMaxWidth()
                    .border(width = 4.dp , shape = RoundedCornerShape(10.dp) , color = BORDER_COLOR)
                    .height(200.dp)
                    .padding(20.dp)
            ){
                vm.changeDirection(it)
            }
        }

        Row(
            modifier = Modifier
                .navigationBarsPadding()
                .padding(start = 20.dp , end = 20.dp , bottom = 20.dp)
                .height(48.dp)
                .fillMaxWidth()
        ) {
            Box(
                modifier = Modifier
                    .weight(1f)
                    .fillMaxHeight()
                    .border(width = 4.dp , shape = RoundedCornerShape(10.dp) , color = BORDER_COLOR)
                    .clip(RoundedCornerShape(10.dp))
                    .clickable{
                        if(state.value.gameState != GameStatus.PLAY){
                            vm.startGame()
                        }else{
                            vm.pauseGame()
                        }
                    },
                contentAlignment = Alignment.Center
            ){
                Text(
                    text = if(state.value.gameState == GameStatus.PLAY) "PAUSE" else "START",
                    color = FONT_COLOR,
                    fontSize = 18.sp,
                    fontWeight = FontWeight.Bold
                )
            }

            Spacer(Modifier.width(20.dp))

            Box(
                modifier = Modifier
                    .weight(1f)
                    .fillMaxHeight()
                    .clip(RoundedCornerShape(10.dp))
                    .border(width = 4.dp , shape = RoundedCornerShape(10.dp) , color = BORDER_COLOR)
                    .clickable {
                        vm.restart()
                    },
                contentAlignment = Alignment.Center
            ){
                Text(
                    text = "RESET",
                    color = FONT_COLOR,
                    fontSize = 18.sp,
                    fontWeight = FontWeight.Bold
                )
            }
        }
    }

    if(state.value.gameState == GameStatus.FINISH){
        GameOverDialog(state.value.score) {
            vm.restart()
        }
    }
}


@Preview
@Composable
fun PreviewGamePage(){
    GamePage()
}